home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’92 / StickyClick 2.0 ƒ / StickyClick 1.2 ƒ / StickyClick.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-18  |  4.4 KB  |  204 lines  |  [TEXT/KAHL]

  1. #include <Traps.h>
  2. #include <GenericPatch.h>
  3. #include <OSUtils.h>
  4. #include <stddef.h>
  5. #include <Extension.h>
  6. #include <Utils.h>
  7. #include <Exceptions.h>
  8. #include "Patches.h"
  9.  
  10. typedef enum {
  11.     eInitialClick,
  12.     eFirstMouseUp,
  13.     eSecondClick,
  14.     eSecondMouseUp
  15. } ClickSet;
  16.  
  17. static PostEventPatch *thePostEventPatch;
  18. static ButtonPatch *theButtonPatch;
  19. static Point theLastMouse;
  20. static ClickSet theClick;
  21. static long theLastTime;
  22. static short theMenuSelect;
  23. static Rect theMenuBarRect;
  24. Point Mouse : 0x830;
  25.  
  26. static Boolean IsTimely(long lastTime)
  27. {
  28.     return (Ticks - (DoubleTime >> 1)) <= lastTime;
  29. }
  30.  
  31. static Boolean IsAround(Point p1, Point p2)
  32. {
  33.     Rect r1, r2, rToss;
  34.  
  35.     r1.top = p1.v - 2;
  36.     r1.bottom = p1.v + 2;
  37.     r1.left = p1.h - 2;
  38.     r1.right = p1.h + 2;
  39.     
  40.     r2.top = p2.v - 2;
  41.     r2.bottom = p2.v + 2;
  42.     r2.left = p2.h - 2;
  43.     r2.right = p2.h + 2;
  44.     
  45.     return SectRect(&r1, &r2, &rToss);
  46. }
  47.  
  48. static Boolean MouseInMenubar()
  49. {
  50.     return PtInRect(Mouse, &theMenuBarRect);
  51. }
  52.  
  53. /******************************************************************************************/
  54.  
  55. ButtonPatch::ButtonPatch()
  56. {
  57.     GenericPatch::InitGenericPatch(_Button, offsetof(ButtonPatchParms, itsResult));
  58.     Install();
  59.     Disable();
  60. }
  61.  
  62. void ButtonPatch::Behavior()
  63. {
  64.     reg ButtonPatchParms *parms = (ButtonPatchParms *) itsFrame->parameters;
  65.     parms->itsResult = -1;
  66.     AbortTrap();
  67. }
  68.  
  69. /******************************************************************************************/
  70.  
  71. PostEventPatch::PostEventPatch()
  72. {
  73.     GenericPatch::InitGenericPatch(_PostEvent, 0);
  74.     Install();
  75. }
  76.  
  77. void PostEventPatch::Behavior()
  78. {
  79.     Disable();
  80.  
  81.     switch ((short) itsFrame->ra0) {
  82.         case mouseUp:
  83.             if ((theClick == eFirstMouseUp)
  84.              && IsAround(Mouse, theLastMouse) 
  85.              && IsTimely(theLastTime) 
  86.              && ((theMenuSelect > 0) || MouseInMenubar())) {
  87.                 theButtonPatch->Enable();
  88.                 AbortTrap();
  89.                 itsFrame->rd0 = noErr;
  90.                 theClick = eSecondClick;
  91.             } else {
  92.                 theClick = eInitialClick;
  93.             }
  94.             theLastMouse = Mouse;
  95.             break;
  96.  
  97.         case mouseDown:
  98.             if (theClick == eInitialClick)
  99.                 theClick = eFirstMouseUp;
  100.             else if (theClick == eSecondClick) {
  101.                 AbortTrap();
  102.                 itsFrame->rd0 = noErr;
  103.                 theButtonPatch->Disable();
  104.                 theClick = eInitialClick;
  105.             }
  106.             theLastTime = Ticks;
  107.             theLastMouse = Mouse;
  108.             break;
  109.     }
  110.  
  111.     Enable();
  112. }
  113.  
  114. /******************************************************************************************/
  115. #if 0
  116. MenuSelectPatch::MenuSelectPatch()
  117. {
  118.     GenericPatch::InitGenericPatch(_MenuSelect, offsetof(MenuSelectParameters, itsResult));
  119.     Install();
  120. }
  121.  
  122. void MenuSelectPatch::Behavior()
  123. {
  124.     reg MenuSelectParameters* params = (MenuSelectParameters*)itsFrame->parameters;
  125.     reg MenuSelectProcPtr oldMenuSelect = (MenuSelectProcPtr) itsOld;
  126.  
  127.     theMenuSelect++;
  128.  
  129.     params->itsResult = (*oldMenuSelect)(params->itsStartPt);
  130.     AbortTrap();
  131.     
  132.     theMenuSelect--;
  133. }
  134. #endif
  135.  
  136. /******************************************************************************************/
  137. #if 1
  138. PopupMenuSelectPatch::PopupMenuSelectPatch()
  139. {
  140.     GenericPatch::InitGenericPatch(_PopUpMenuSelect, offsetof(PopupMenuSelectParameters, itsResult));
  141.     Install();
  142. }
  143.  
  144. void PopupMenuSelectPatch::Behavior()
  145. {
  146.     reg PopupMenuSelectParameters* params = (PopupMenuSelectParameters*)itsFrame->parameters;
  147.     reg PopupMenuSelectProcPtr oldMenuSelect = (PopupMenuSelectProcPtr) itsOld;
  148.  
  149.     theMenuSelect++;
  150.  
  151.     params->itsResult = (*oldMenuSelect)(params->itsMenuHandle, params->itsTop, params->itsLeft, params->itsItem);
  152.     AbortTrap();
  153.     
  154.     theMenuSelect--;
  155. }
  156. #endif
  157.  
  158. /******************************************************************************************/
  159. void Install()
  160. {
  161.     theClick = eInitialClick;
  162.     theMenuSelect = 0;
  163.     
  164.     try {
  165.         if (true
  166.         && ((thePostEventPatch = new PostEventPatch) != nil)
  167.         && ((theButtonPatch = new ButtonPatch) != nil)
  168. //        && (new MenuSelectPatch != nil)
  169.         && (new PopupMenuSelectPatch != nil)
  170.         ) {
  171.             // if extension succeeds, show happy icon.
  172.             SysEnvRec environment;            // machine configuration.
  173.             
  174.             // find out what kind of machine this is.
  175.             SysEnvirons(curSysEnvVers, &environment);
  176.  
  177.             if (environment.hasColorQD && MainDevice)
  178.                 theMenuBarRect = (**MainDevice).gdRect;
  179.             else {
  180.                 theMenuBarRect = _qd.screenBits.bounds;
  181.             }
  182.         
  183.             theMenuBarRect.bottom = theMenuBarRect.top + 0x14;
  184.  
  185.             ShowIconFamily(128);
  186.         } else {
  187.             throw(memFullErr);
  188.         }
  189.     } /* try */
  190.  
  191.     catch {
  192.         // extension failed, show sad icon.
  193.         ShowIconFamily(129);
  194.         throw(theException);
  195.     }
  196. }
  197.  
  198. // called when system is shutdown.
  199.  
  200. void Remove()
  201. {    
  202.     Patch::RemoveAll();
  203. }
  204.